﻿using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Utk.Nlp;

namespace Utk
{
    static class Knowledge
    {
        public static readonly Pattern AffermativeResponse = new Pattern(
            "Да",
            "Угу",
            "Ага");

        public static readonly Pattern NegativeResponse = new Pattern(
            "Нет",
            "Не-а",
            "Неа");

        public static readonly Pattern DescribeItRequest = new Pattern(
            "Опиши",
            "Валяй",
            "Расскажи");

        public static readonly Pattern GotItResponse = new Pattern(
            "Понял",
            "Ага",
            "Принято");

        public static readonly Pattern HelloMessage = new Pattern(
            "Привет",
            "Здравствуй",
            "Здорово");

        public static readonly YesNoRequest HaveMoreRequest = "Ещё?";

        public static readonly EntryType Problem = new EntryType
            {
                InternalName = "Problem",
                InitiationRequest = new Pattern(
                    "есть проблема",
                    "у меня проблема"),
                ExpectationMismatchRequest = "Что-то не похоже на проблему. Это точно она?",
                TypeConfirmationRequest = "Это проблема?",
                Classificator = new FrequencyClassificator(
                    "не работает",
                    "проблема",
                    "плохо",
                    "мало",
                    "слишком",
                    "недостаточно")
            };

        public static readonly EntryType Cause = new EntryType
        {
            InternalName = "Cause",
            InitiationRequest = new Pattern(
                "есть причина",
                "знаю причину"),
            ExpectationMismatchRequest = "Что-то не похоже на описаниы причины. Это точно она?",
            TypeConfirmationRequest = "Это причина?",
            Classificator = new FrequencyClassificator(
                "потому",
                "следствие",
                "следствии",
                "поскольку",
                "от того",
                "по причине")
        };

        public static readonly EntryType Hypothesis = new EntryType
            {
                InternalName = "Hypothesis",
                InitiationRequest = new Pattern(
                    "есть гипотеза",
                    "есть теория"),
                ExpectationMismatchRequest = "Что-то не похоже на гипотезу. Это точно она?",
                TypeConfirmationRequest = "Это гипотеза?",
                Classificator = new FrequencyClassificator(
                    "наверное",
                    "я думаю",
                    "возможно",
                    "гипотетически",
                    "вероято",
                    "может быть")
            };

        public static readonly EntryType Experiment = new EntryType
        {
            InternalName = "Experiment",
            InitiationRequest = new Pattern("есть проверяемое следствие"),
            ExpectationMismatchRequest = "Что-то не похоже на проверяемое следствие. Это точно она?",
            TypeConfirmationRequest = "Это проверяемое следствие гипотезы?",
            Classificator = new FrequencyClassificator(
                "должно",
                "должен",
                "если",
                "в случае")
        };

        public static readonly EntryType Task = new EntryType
            {
                InternalName = "Task",
                InitiationRequest = "есть задача",
                ExpectationMismatchRequest = "Что-то не похоже на задачу. Это точно она?",
                TypeConfirmationRequest = "Это задача?",
                Classificator = new FrequencyClassificator(
                    "надо",
                    "сделать",
                    "реализовать",
                    "хочу",
                    "задача",
                    "выполнить")
            };

        public static readonly LinkType ProblemCauseHypothesis = new LinkType
            {
                StartEntryType = Cause,
                EndEntryType = Problem,
                StartToEndRequest = "Есть предположения о последствиях?",
                EndToStartRequest = "Есть предположения о причинах проблемы?"
            };

        public static readonly LinkType HypothesisExperimentLink = new LinkType
        {
            StartEntryType = Experiment,
            EndEntryType = Hypothesis,
            StartToEndRequest = "Есть понимание, что из этого следует?",
            EndToStartRequest = "Можно ли как-то проверить это предположение?"
        };

        public static readonly IEnumerable<EntryType> EntryTypes;

        public static readonly IEnumerable<LinkType> LinkTypes;

        static Knowledge()
        {
            EntryTypes = ExtractListOf<EntryType>();
            LinkTypes = ExtractListOf<LinkType>();
        }

        static T[] ExtractListOf<T>()
        {
            var fields = typeof(Knowledge).GetFields(BindingFlags.Static | BindingFlags.Public);
            return fields.Where(_ => _.FieldType == typeof(T)).Select(_ => _.GetValue(null)).Cast<T>().ToArray();
        }
    }
}